package com.qianfeng.smartdevices.service.impl;


//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼            BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qianfeng.smartdevices.cache.AreasCache;
import com.qianfeng.smartdevices.cache.CategoriesCache;
import com.qianfeng.smartdevices.dto.ResultCode;
import com.qianfeng.smartdevices.event.ColorCommandEvent;
import com.qianfeng.smartdevices.event.PowerCommandEvent;
import com.qianfeng.smartdevices.event.UpdateDevicesStatusEvent;
import com.qianfeng.smartdevices.exceptions.AddErrorException;
import com.qianfeng.smartdevices.exceptions.DeleteErrorException;
import com.qianfeng.smartdevices.exceptions.MybaseException;
import com.qianfeng.smartdevices.exceptions.UpdateErrorException;
import com.qianfeng.smartdevices.mapper.DeviceMapper;
import com.qianfeng.smartdevices.pojo.CheckStatus;
import com.qianfeng.smartdevices.pojo.Device;
import com.qianfeng.smartdevices.service.DeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * Created by jackiechan on 2020/12/13 14:05
 *
 * @Author jackiechan
 */
@Service
@Transactional
public class DeviceServiceImpl implements DeviceService {


    private DeviceMapper deviceMapper;


    private AreasCache areasCache;
    @Autowired
    public void setAreasCache(AreasCache areasCache) {
        this.areasCache = areasCache;
    }

    private CategoriesCache categoriesCache;
    @Autowired
    public void setCategoriesCache(CategoriesCache categoriesCache) {
        this.categoriesCache = categoriesCache;
    }

    @Autowired
    public void setDeviceMapper(DeviceMapper deviceMapper) {
        this.deviceMapper = deviceMapper;
    }




    @Autowired
    private ApplicationContext context;

    @Override
    public void AddDevice(Device device) {
        if (device == null || device.isNull(CheckStatus.ADD)) {
            throw new AddErrorException("数据不能为空", ResultCode.DATA_NOT_ALLOW_NUL);
        }
        try {
            deviceMapper.AddDevice(device);
        } catch (Exception e) {
            e.printStackTrace();
            throw new AddErrorException("添加失败", ResultCode.ERROR);
        }

    }

    @Override
    public void updateDevice(Device device) {
        if (device == null || device.isNull(CheckStatus.UPDATE)) {
            throw new UpdateErrorException("数据为空", ResultCode.DATA_NOT_ALLOW_NUL);
        }
        try {
            deviceMapper.updateDevice(device);
        } catch (Exception e) {
            e.printStackTrace();
            throw new UpdateErrorException("更新失败", ResultCode.ERROR);
        }
    }

    @Override
    public Device getDeviceById(Long id) {
        if (id == null || id == 0) {
            throw new MybaseException("数据为空", ResultCode.DATA_NOT_ALLOW_NUL);
        }

        try {
            Device device = deviceMapper.getDeviceById(id);
            if (device == null) {
                throw new MybaseException("查询失败", ResultCode.ERROR);
            }
//            WebSocketSession session = DevicePowerWebSocketHandler.getClient(device.getDevicesuuid());
//            if (session != null && session.isOpen()) {
//                device.setStatus("1");//设置在线
//            }
//            context.publishEvent(device);//更新设备状态

//        Category category = categoriesCache.get(device.getCategoryid());//从缓存获取分类对象
//        Area area = areanCache.get(device.getAreaid());//从缓存获取区域数据
//        device.setCategory(category);//设置分类
//        device.setAreaid(area.getId());//设置区域
//        device.setAreaname(area.getAreaname());

            return device;
        } catch (Exception e) {
            e.printStackTrace();
            throw new MybaseException("查询失败", ResultCode.ERROR);

        }
    }

    @Override
    public Device getDeviceByUUId(String uuid) {
        if (StringUtils.isEmpty(uuid)) {
            throw new MybaseException("数据为空", ResultCode.DATA_NOT_ALLOW_NUL);
        }

        Device device = deviceMapper.getDeviceByUUId(uuid);
//        Category category = categoriesCache.get(device.getCategoryid());//从缓存获取分类对象
//        Area area = areanCache.get(device.getAreaid());//从缓存获取区域数据
//        device.setCategory(category);//设置分类
//        device.setAreaid(area.getId());//设置区域
//        device.setAreaname(area.getAreaname());
        return device;
    }

    @Override
    public PageInfo<Device> getAllDevices(int pageNum, int pageSize, String address, int status, int direction, int areaid, int categoryid) {
        PageHelper.startPage(pageNum, pageSize);
        try {
            List<Device> deviceList = deviceMapper.getAllDevices(address, status, direction, areaid, categoryid);
            //我们上面查询的数据中没有分类信息,需要设置
            //分类信息在缓存中,直接查缓存就可以
            //每个设备的分类可能不一样,怎么知道哪个分类
            deviceList.forEach(device ->{
                device.setCategory(categoriesCache.get(device.getCategoryid()));
                device.setAreaname(areasCache.get(device.getAreaid()).getAreaname());
            });
            return new PageInfo<>(deviceList);
        } catch (Exception e) {
            e.printStackTrace();
            throw new MybaseException("查询异常", ResultCode.ERROR);
        }
    }

    @Override
    public void deleteDevices(List<String> ids) {
        if (ids == null || ids.size() == 0) {
            throw new DeleteErrorException("没有传递 id", ResultCode.ERROR);
        }

        try {
            deviceMapper.deleteDevices(ids);
        } catch (Exception e) {
            e.printStackTrace();
            throw new DeleteErrorException("删除失败", ResultCode.ERROR);
        }
    }
    @Override
    public void sendCommand(String uuid, String command) {
        //根据标识找到设备的会话
        String value = null;
        switch (command) {

            case "open":
                value = "0";
                break;
            case "close":
                value = "1";
                break;
            case "change":
                value = "2";
                context.publishEvent(new ColorCommandEvent(uuid, value));
                return;
        }

        //通过会话将指令发送出去
        System.err.println(Thread.currentThread().getName());
        context.publishEvent(new PowerCommandEvent(uuid, value));
    }

    @Override
    public void updateStatus(String uuid, String status) {
        deviceMapper.updateOffLine(uuid, status);
    }

    @Override
    @EventListener
    @Async
    public void onEvent(UpdateDevicesStatusEvent event) {
        updateStatus(event.getUuid(), event.getStatus());
    }


}
